package com.googlecode.dgwt.client.dijit.form.base;

import com.googlecode.dgwt.client.dijit.base.selection.Selection;
import com.googlecode.dgwt.client.dijit.base.selection.SelectionMode;
import com.googlecode.dgwt.client.dijit.base.widget.ViewHandler;
import com.googlecode.dgwt.client.dijit.base.widget.WidgetHandler;
import com.googlecode.dgwt.client.dijit.form.FormWidget;
import com.googlecode.dgwt.client.dijit.form.base.view.ListBoxView;
import com.googlecode.dgwt.client.dojo.data.KeyValueStore;
import com.googlecode.dgwt.client.dojo.data.base.ModeledStore;
import com.googlecode.dgwt.client.dojo.exception.DojoRuntimeException;
import com.googlecode.dgwt.client.dojo.exception.ValidationException;

/**
 * @author wellsantos@wellsantos.com
 * @since 0.01
 */
public class ListBoxBase extends FormWidget {

    private ListBoxView listBoxView;
    private ModeledStore<Object> store;
    private boolean userDefinedStore;
    
    protected ListBoxBase(boolean ready) {
        super(ready);
    }

    protected ListBoxView createListBoxView(){
        return new ListBoxView(isMultiple() ? SelectionMode.MULTIPLE : SelectionMode.SINGLE);
    }
        
    @Override
    protected WidgetHandler createHandler() {
        listBoxView = createListBoxView();
        return new ViewHandler(listBoxView, super.createHandler());
    }

    @Override
    protected void buildRendering() {
        super.buildRendering();
        assert (getElement() != null);
        getListBoxView().getWidget().setWidth("100%");
        getContainerElement().appendChild(getListBoxView().getWidget().getElement());
        setFocusableElement(getListBoxView().getCellView().getFocusableElement());
    }

    @Override
    protected void onPostCreate() {
        super.onPostCreate();
        if (store == null){
            setStore(null);
        }
    }

    protected boolean isUserDefinedStore(){
        return userDefinedStore;
    }

    protected ListBoxView getListBoxView() {
        return listBoxView;
    }
    
    public ModeledStore<?> getStore() {
        return store;
    }

    @SuppressWarnings("unchecked")
    public void setStore(ModeledStore<?> newStore) {
        if (newStore == null){
            // take advantage of current store if possible
            if (store == null || userDefinedStore){            
                store = (ModeledStore) new KeyValueStore(10);        
            } else {
                store.clear();
            }
            userDefinedStore = false;
        } else {
            userDefinedStore = true;
            store = (ModeledStore) newStore;
        }
        getListBoxView().setStore(store);
    }
    
    public void addItem(String displayText){
        addItem(displayText, displayText);
    }
    
    public void addItem(String value, String displayText){
        addItem(store.size(), value, displayText);
    }
    
    public void addItem(int index, String displayText){
        addItem(index, displayText, displayText);
    }
    
    public void addItem(int index, String value, String displayText){
        Object item = store.addNew(index);
        try {
            store.setDisplayValues(item, value, displayText);
        } catch (ValidationException e) {
            throw new DojoRuntimeException(this, "Unable to add an item. Please use the Store directly.", e);
        }
    }
    
    public Object getItem(int index){
        return store.get(index);
    }
    
    public String getItemValue(int index){
        return getListBoxView().getValueColumn().getDisplayValue(store.get(index));
    }
    
    public String getItemText(int index){
        return getListBoxView().getTextColumn().getDisplayValue(store.get(index));
    }
    
    public void setItemValue(int index, String value){
        try {
            getListBoxView().getValueColumn().setDisplayValue(store.get(index), value);
        } catch (ValidationException e) {
            throw new DojoRuntimeException(this, "Unable to update an item. Please use the Store directly.", e);
        }
    }
    
    public void getItemText(int index, String displayText){
        try {
            getListBoxView().getTextColumn().setDisplayValue(store.get(index), displayText);
        } catch (ValidationException e) {
            throw new DojoRuntimeException(this, "Unable to update an item. Please use the Store directly.", e);
        }
    }
    
    public void removeItem(int index){
        store.remove(index);
    }
    
    public int getItemCount(){
        return store.size();
    }
    
    public int getSelectedIndex(){
        return getSelection().getSelected();
    }
    
    public void setSelectedIndex(int index){
        getSelection().setSelected(index);
    }
    
    public String getSelectedValue(){
        Object item = getSelectedItem();
        return item == null ? null : getListBoxView().getValueColumn().getDisplayValue(item);
    }
    
    public void setSelectedValue(String value){
        setSelectedItem(store.findByDisplayValues(value));
    }
    
    public void setSelectedText(String displayText){
        setSelectedItem(store.findByDisplayValues(1, displayText));
    }
    
    public String getSelectedText(){
        Object item = getSelectedItem();
        return item == null ? null : getListBoxView().getTextColumn().getDisplayValue(item);
    }
    
    public Object getSelectedItem(){
        int row = getSelection().getSelected();
        return row == -1 ? null : getStore().get(row);
    }
    
    public void setSelectedItem(Object storeItem){
        getSelection().setSelected(getStore().indexOf(storeItem));
    }
    
    public Selection getSelection(){
        return getListBoxView().getCellView().getSelection();
    }

    public boolean isMultiple(){
        return true;
    }
    
    @Override
    public String getText() {
        return getSelectedText();
    }

    @Override
    public void setText(String text) {
        setSelectedText(text);
    }

    @Override
    public boolean isEmpty() {
        return getSelectedIndex() == -1;
    }

    @Override
    public void setName(String name) {
        // TODO Auto-generated method stub
        super.setName(name);
    }

}
